<

シェーダーコンパイルのジャンク

モバイル アプリのアニメーションが不安定に見える場合は、 ただし最初の実行時のみ、 これはシェーダーのコンパイルが原因である可能性があります。 Flutter の長期的なソリューション シェーダーコンパイルのジャンクはインペラ、 これは iOS の安定版リリースに含まれています Android ではフラグの背後にあるプレビューで表示されます。

私たちは、Imeller を完全に量産できる状態にすることに取り組んでいますが、 バンドルすることでシェーダーコンパイルのジャンクを軽減できます iOS アプリを使用したプリコンパイル済みシェーダー。 残念ながら、このアプローチは Android ではうまく機能しません プリコンパイルされたシェーダはデバイスまたは GPU 固有であるためです。 Android ハードウェア エコシステムは十分に大きいため、 アプリケーションにバンドルされた GPU 固有のプリコンパイル済みシェーダー 一部のデバイスのみで動作しますが、 他のデバイスではジャンクが悪化する可能性が高く、 レンダリを作成することもできますngエラー。

また、作成する予定はありませんのでご了承ください。 作成時の開発者エクスペリエンスの改善 以下で説明するプリコンパイル済みシェーダー。その代わり、 私たちはより堅牢な製品にエネルギーを集中しています。 Impeller が提供するこの問題の解決策。

シェーダーコンパイルジャンクとは何ですか?

シェーダは、上で実行されるコードの一部です。 GPU (グラフィックス プロセッシング ユニット)。 Flutter がレンダリングに使用する Skia グラフィックス バックエンド 新しい一連の描画コマンドを初めて目にします。 場合によっては、 そのコマンド シーケンスのカスタム GPU シェーダ。 これにより、そのシーケンスと潜在的に類似したシーケンスが許可されます。 できるだけ速くレンダリングするため。

残念ながら、Skia のシェーダーの生成とコンパイルは フレームワークロードに合わせて順番に発生します。 コンパイルには最大で数百ミリ秒かかる場合があります 一方、滑らかなフレームは 16 ミリ秒以内に描画する必要があります。 60 fps (フレーム/秒) 表示の場合。 したがって、コンパイルによって数十のフレームが発生する可能性があります。 見逃され、fps が 60 から 6 に低下します。 これはコンパイルジャンク。 コンパイルが完了したら、 アニメーションはスムーズでなければなりません。

一方、Impeller はすべてを生成してコンパイルします。 flutter エンジンを構築するときに必要なシェーダー。 したがって、Impeller 上で実行されているアプリはすでに 必要なすべてのシェーダーがあり、シェーダーを使用できます アニメーションにジャンクを持ち込まずに。

シェーダーコンパイルジャンクの存在の決定的な証拠 設定することですGrGLProgramBuilder::finalizeトレース中 と--trace-skia有効になりました。 次のスクリーンショットは、タイムライン トレースの例を示しています。

A tracing screenshot verifying jank

「最初の実行」とは何を意味しますか?

iOS では、「初回実行」とは、ユーザーが アニメーションが最初に発生するたびにジャンクが発生する ユーザーはアプリを最初から開きます。

SkSLウォームアップの使い方

Flutter はコマンドライン ツールを提供します アプリ開発者が必要となる可能性のあるシェーダーを収集するため SkSL (Skia Shader Language) 形式のエンドユーザー向け。 その後、SkSL シェーダーをアプリにパッケージ化できます。 エンドユーザーが最初に使用するときにウォームアップ (プリコンパイル) が行われます。 アプリを開くため、コンパイルが削減されます 後のアニメーションでジャンクが発生します。 収集するには次の手順を使用してください そして、SkSL シェーダをパッケージ化します。

  1. でアプリを実行します--cache-skslオン SkSL でシェーダをキャプチャするには:

    flutter run --profile --cache-sksl
    

    同じアプリが以前に実行されていた場合 それなし--cache-sksl、 そうして--purge-persistent-cacheフラグが必要になる場合があります:

    flutter run --profile --cache-sksl --purge-persistent-cache
    

    このフラグは、古い非 SkSL シェーダ キャッシュを削除します。 SkSL シェーダのキャプチャを妨げる可能性があります。 SkSL シェーダもパージするので使用してくださいそれだけ初めて--cache-sksl走る。

  2. アプリを操作して、できるだけ多くのアニメーションをトリガーします 必要に応じて;特にコンパイルジャンクのあるもの。

  3. プレスMコマンドラインでa3de49d3-7947​​-43d4-8652-6d9801fad5e5に キャプチャした SkSL シェーダを次のような名前のファイルに書き込みますflutter_01.sksl.json。 最良の結果を得るには、 実際の iOS デバイスで SkSL シェーダをキャプチャします。 シミュレータでキャプチャされたシェーダは正しく動作しない可能性があります 実際のハードウェア上で。

  4. 以下を使用して、SkSL ウォームアップでアプリをビルドします。 適切に:

    flutter build ios --bundle-sksl-path flutter_01.sksl.json
    

    次のようなドライバーテスト用に構築されている場合test_driver/app.dart、 も必ず指定してください--target=test_driver/app.dart(例えば、flutter build ios --bundle-sksl-path flutter_01.sksl.json --target=test_driver/app.dart)。

  5. 新しく構築されたアプリをテストします。

あるいは、いくつかの統合テストを作成して、 単一のコマンドを使用して最初の 3 つのステップを自動化します。 例えば:

flutter drive --profile --cache-sksl --write-sksl-on-exit flutter_01.sksl.json -t test_driver/app.dart

そのような統合テスト、 簡単かつ確実に入手できます アプリのコードが変更されたときの新しい SkSL、 または Flutter がアップグレードされたとき。 このようなテストは、パフォーマンスの変化を検証するためにも使用できます。 SkSLのウォームアップの前後。 さらに良いことに、これらのテストを CI(継続的インテグレーション)システムなので、 SkSL は、アプリの存続期間全体にわたって自動的に生成およびテストされます。

オリジナルバージョンを取得してください flutterギャラリー例として。 CI システムは、Flutter コミットごとに SkSL を生成するように設定されています。 そしてパフォーマンスを検証します。transitions_perf_test.dartテスト。 詳細については、 をチェックしてくださいflutter_gallery_sksl_warmup__transition_perfflutter_gallery_sksl_warmup__transition_perf_e2e_ios32タスク。

最悪のフレーム ラスタライズ時間は、次の有益な指標です。 シェーダの重大度を示すためのこのような統合テスト コンピレーションのジャンク。 例えば、 上記の手順により、Flutter ギャラリーのシェーダー コンパイルが削減されます。 ジャンクが発生し、最悪のフレーム ラスタライズ時間が短縮されます。 Moto G4 は約 90 ミリ秒から約 40 ミリ秒に。 iPhone 4sでは、 約 300 ミリ秒から約 80 ミリ秒に短縮されます。それがビジュアルに繋がる この記事の冒頭で説明したように、違いがあります。